/*
 * Copyright 2018-2021 guerlab.net and other contributors.
 *
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.guerlab.smart.pay.web.alipay;

import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import net.guerlab.smart.pay.core.exception.AlipayConfigInvalidException;
import net.guerlab.smart.pay.service.entity.AlipayConfig;
import net.guerlab.smart.pay.service.properties.PayProperties;
import net.guerlab.smart.pay.service.service.AlipayConfigService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 抽象支付宝支付控制器
 *
 * @author guer
 */
public abstract class AbstractAlipayController {

    /**
     * 应用ID关键字
     */
    protected static final String KEY_APP_ID = "appId";

    protected AlipayConfigService configService;

    protected PayProperties payProperties;

    /**
     * 获取支付渠道名称
     *
     * @return 支付渠道名称
     */
    final String getPayChannel() {
        return "ALIPAY_" + getAlipayTradeType().name();
    }

    /**
     * 获取支付宝支付类型
     *
     * @return 支付宝支付类型
     */
    protected abstract AlipayTradeType getAlipayTradeType();

    /**
     * 构造支付宝客户端
     *
     * @param appId
     *         应用ID
     * @return 支付宝客户端
     */
    protected AlipayClient buildAlipayClient(String appId) {
        return buildAlipayClient(appId, false);
    }

    /**
     * 构造支付宝客户端
     *
     * @param config
     *         应用配置
     * @return 支付宝客户端
     */
    protected AlipayClient buildAlipayClient(AlipayConfig config) {
        return buildAlipayClient(config, false);
    }

    /**
     * 构造支付宝客户端
     *
     * @param appId
     *         应用ID
     * @param checkEnable
     *         检查是否启用
     * @return 支付宝客户端
     */
    protected AlipayClient buildAlipayClient(String appId, boolean checkEnable) {
        return buildAlipayClient(configService.selectByIdOptional(appId).orElseThrow(AlipayConfigInvalidException::new),
                checkEnable);
    }

    /**
     * 构造支付宝客户端
     *
     * @param config
     *         应用配置
     * @param checkEnable
     *         检查是否启用
     * @return 支付宝客户端
     */
    protected AlipayClient buildAlipayClient(AlipayConfig config, boolean checkEnable) {
        if (config == null) {
            throw new AlipayConfigInvalidException();
        }
        if (checkEnable && !config.getEnable()) {
            throw new AlipayConfigInvalidException();
        }

        String gatewayUrl = AlipayUrlConstants.gateway(config.getEnableDevEnv());

        return new DefaultAlipayClient(gatewayUrl, config.getAppId(), config.getPrivateKey(), AlipayConstants.FORMAT_JSON, AlipayConstants.CHARSET_UTF8, config.getAlipayPublicKey(),
                AlipayConstants.SIGN_TYPE_RSA2);
    }

    @Autowired
    public void setConfigService(AlipayConfigService configService) {
        this.configService = configService;
    }

    @Autowired
    public void setPayProperties(PayProperties payProperties) {
        this.payProperties = payProperties;
    }
}
